package edu.uwm.cs552;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Stroke;
import java.util.LinkedList;
import java.util.Observable;

/**
 * The status of a player's train.
 * Other players only see an icon for the train's location.
 * The player can see their proposed journey.
 */
public class TrainStatus extends Observable {

	private HexCoordinate currentLocation;
	
	private LinkedList<HexCoordinate> plans = new LinkedList<HexCoordinate>();
	
	public HexCoordinate getLocation() {
		return currentLocation;
	}
	
	public static final int ALPHA = 0x40000000; // alpha component for proposed travel
	
	public void draw(Graphics2D g, double scale, boolean showPlans) {
		if (showPlans) {
			Color oldColor = g.getColor();
			g.setColor(new Color((oldColor.getRGB()&0xffffff)|ALPHA,true));
			for (HexCoordinate h : plans) {
				Polygon p = h.toPolygon(scale);
				g.fillPolygon(p);
			}
			g.setColor(oldColor);
		}
		if (currentLocation != null) {
			Stroke old = g.getStroke();
			g.setStroke(getStroke(scale));
			Point p = currentLocation.toPoint(scale);
			int size = (int)(scale/2);
			g.drawLine(p.x-size, p.y-size, p.x+size, p.y+size);
			g.drawLine(p.x+size, p.y-size, p.x-size, p.y+size);
			g.setStroke(old);
		}
	}

	private transient float lastScale = 0;
	private transient Stroke lastStroke = null;
	
	private Stroke getStroke(double scale) {
		if (scale == lastScale) return lastStroke;
		lastScale = (float)scale;
		float width = lastScale / 10;
		lastStroke = new BasicStroke(width,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
		return lastStroke;
	}

	public HexCoordinate nextPlanned() {
		return plans.poll();
	}
	
	public void pushPlanned(HexCoordinate h) {
		plans.addFirst(h);
		setChanged();
		notifyObservers(h);
	}
	
	public void addPlanned(HexCoordinate h) {
		if (!plans.isEmpty() && plans.getLast().equals(h)) return;
		plans.addLast(h);
		setChanged();
		notifyObservers(h);
	}
	
	public void removePlanned(HexCoordinate h) {
		if (plans.remove(h)) setChanged();
		notifyObservers();
	}

	public void clearPlanned() {
		plans.clear();
		setChanged();
		notifyObservers(null);
	}
	
	public void move(HexCoordinate h) {
		if (!h.equals(currentLocation)) setChanged();
		currentLocation = h;
		notifyObservers(h);
	}
}
